package com.sharemarking.system.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.sharemarking.system.entity.Menu;
import com.sharemarking.system.entity.Permission;
import com.sharemarking.system.mapper.MenuMapper;
import com.sharemarking.system.mapper.PermissionMapper;
import com.sharemarking.system.service.MenuService;

@Controller
@RequestMapping("system/menu")
public class MenuController {
	
	@Autowired
	private MenuMapper mm;
	
	@Autowired
	private PermissionMapper pm;
	
	@Autowired
	private MenuService ms;
	
	/**
	 * 菜单首页
	 * @param e
	 * @param model
	 */
	@GetMapping("index")
	@PreAuthorize("hasPermission('base','all')")
	public void index(Integer menuId,Model model){
		Iterable<Menu> it=ms.getAllMenus();
		Menu targetMenu=null;
		for(Menu m:it)if(m.getParentId()==null){targetMenu=m;break;}
		if(menuId==null&&targetMenu!=null)menuId=targetMenu.getId();
		model.addAttribute("menus",it);
		model.addAttribute("targetMenuId", menuId);
		model.addAttribute("permissions", pm.getAll());
	}
	
	/**
	 * 新增菜单模块页面
	 * @return
	 */
	@GetMapping("0")
	@PreAuthorize("hasPermission('base','all')")
	public String addPage(Model model){
		model.addAttribute("obj", new Menu());
		List<Permission> list=pm.getAll();
		Set<String> domain=new HashSet<String>();
		for(Permission p:list)domain.add(p.getDomain());
		model.addAttribute("menuNodes", new ArrayList<Menu>(0));
		model.addAttribute("domains", domain);
		model.addAttribute("permissions", list);
		return "system/menu/form";
	}
	
	/**
	 * 菜单模块页面
	 * @param e
	 * @return
	 */
	@GetMapping("{id}")
	@PreAuthorize("hasPermission('base','all')")
	public String get(@PathVariable("id") int id,Model model){
		Menu menu=mm.get(id);
		if(menu==null)return "error/null";
		model.addAttribute("obj", menu);
		List<Permission> list=pm.getAll();
		Set<String> domain=new HashSet<String>();
		for(Permission p:list)domain.add(p.getDomain());
		Iterable<Menu> it=ms.getAllMenus();
		List<Menu> menuNodes=new ArrayList<Menu>();
		for(Menu m:it)if(m.getParentId()!=null && m.getParentId()==id)menuNodes.add(m);
		model.addAttribute("menuNodes", menuNodes);
		model.addAttribute("domains", domain);
		model.addAttribute("permissions", list);
		return "system/menu/form";
	}
	
	/**
	 * 新增菜单模块
	 * @param target
	 * @param model
	 * @return
	 */
	@PostMapping("0")
	@PreAuthorize("hasPermission('base','all')")
	@Transactional
	public String add(MenuDto target,Model model){
		target.setParentId(null);
		mm.insert(target);
		target.getMenuNodes();
		if(target.getMenuNodes()!=null)target.getMenuNodes().removeIf(m->StringUtils.isEmpty(m.getName()));
		if(target.getMenuNodes()!=null)target.getMenuNodes().forEach(m->{
			m.setParentId(target.getId());
			mm.insert(m);
		});
		return "redirect:index";
	}
	/**
	 * 更新菜单模块
	 * @param e
	 * @return
	 */
	@PostMapping("{id}")
	@PreAuthorize("hasPermission('base','all')")
	@Transactional
	public String update(MenuDto target,Model model){
		if(target.getId()==null)return "error/null";
		mm.updateInfo(target);
		if(target.getMenuNodes()==null)target.setMenuNodes(new ArrayList<Menu>(0));
		target.getMenuNodes().removeIf(m->StringUtils.isEmpty(m.getName()));
		List<Menu> menuNodes=target.getMenuNodes();
		menuNodes.stream().forEach(m->{
			if(m.getId()!=null){
				mm.updateInfo(m);
			}else{
				m.setParentId(target.getId());
				mm.insert(m);
			}
		});
		List<Integer> menuNodesIdList=menuNodes.stream().map(m->m.getId()).collect(Collectors.toList());
		Iterable<Menu> it=ms.getAllMenus();
		it.forEach(m->{
			if(m.getParentId()==target.getId()&&!menuNodesIdList.contains(m.getId())){
				mm.delete(m.getId());
			}
		});
		return "redirect:index";
	}
	/**
	 * 删除指定菜单
	 * @param id
	 */
	@GetMapping("{id}/delete")
	@PreAuthorize("hasPermission('base','all')")
	@Transactional
	public String delete(@PathVariable("id")int id){
		mm.deleteChild(id);
		mm.delete(id);
		return "redirect:../index";
	}
	
	public static class MenuDto extends Menu{
		
		private List<Menu> menuNodes;

		public List<Menu> getMenuNodes() {
			return menuNodes;
		}

		public void setMenuNodes(List<Menu> menuNodes) {
			this.menuNodes = menuNodes;
		}
		
	}
	
}
